mod api;
mod config;
mod global;
mod subcmd;
use std::env;

use api::oss;
use tokio;
use rcmd_core::clap::{Arg, Command};
use rcmd_core::log::*;
use rcmd_core::{chrono, fern};



#[tokio::main]
async fn main() { 
    // init logger
    let _ret = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "[dpm][{}]-[{}]: {}",
                chrono::Local::now().format("%H:%M:%S"),
                record.level(),
                message
            ))
        })
        .level(if cfg!(debug_assertions) {
            LevelFilter::Debug
        } else {
            LevelFilter::Info
        })
        .chain(std::io::stdout())
        .apply();
    // The YAML file is found relative to the current file, similar to how modules are found
    let mut cmd = Command::new("dpm");
    let mts = cmd
        .clone()
        .version("0.1.0")
        .author("dwb <dwb@dwb.ren>")
        .about("Private package manager for D.")
        .args([Arg::new("path").short('p').help("path to init")])
        .subcommand(Command::new("init").about("init dpm's config in *current path* or"))
        .subcommand(
            Command::new("install")
                .about("install plugin in *current path*")
                .args([Arg::new("plugin").required(true).help("the plugin name")]),
        )
        .subcommand(Command::new("publish").about("publish the plugin in *current path*"))
        .subcommand(Command::new("login").about("login by oauth2 api, default *API* IS GITHUB"))
        .subcommand(Command::new("list").about("showout the list of dpm's package install in path"))
        .subcommand(Command::new("add_runtime")
            .about("create a new runtime@ver")
            .args([Arg::new("name").required(true).help("the runtime name"),
            Arg::new("ver").required(true).help("the runtime ver")]),)
        .get_matches();

    let p =  mts.get_one::<String>("path");
    if p.is_some(){
        let _ = env::set_var("DPM_WORKPATH", p.unwrap());
    }


    match mts.subcommand() {
        Some(("init", sub_matchs)) => subcmd::init::handle(sub_matchs).await,
        Some(("publish", sub_matchs)) => subcmd::publish::handle(sub_matchs).await,
        Some(("install", sub_matchs)) => subcmd::install::handle(sub_matchs).await,
        Some(("add_runtime", sub_matchs)) => subcmd::add_runtime::handle(sub_matchs).await,
        Some(("list", sub_matchs)) => subcmd::list::handle(sub_matchs).await,
        Some(("login", _sub_matchs)) => todo!(),
        _ => { 
            cmd.print_help().unwrap();
        }
    }
}

#[test]
fn test_reg() {
    extern crate regex;

    use regex::Regex;
    use std::collections::HashSet;
    let tweet = "Hey #world, I just got my new #dog, say hello to Till. #dog #forever #2 #_ ";
    let reg = Regex::new(r"\#[a-zA-Z][0-9a-zA-Z_]*").unwrap();
    let tags: HashSet<&str> = reg.find_iter(tweet).map(|mat| mat.as_str()).collect();
    println!("{:?}", tags);
    assert!(tags.contains("#dog") && tags.contains("#forever") && tags.contains("#world"));
    assert_eq!(tags.len(), 3);
}
